<?php
header("Content-type: text/html; charset=utf-8");
include "chooseOneStock.php";
// 参数定义
$train_fenxi = array();  // 持股周期的训练结果
$train_res = array(); //多次训练的最优结果
$test_fenxi = array();  // 测试结果

$history = array();     // 记录历史明细
$AllHistory = array();
$AllLineChart = array();
$AllBingTu = array();
$AllarrayCalDay = array();
$bing_json_string;
@$orderRule = $_REQUEST["order"];   // 排序规则
// $orderRule = 'ts_code';  // 排序规则
@$HoldLimit = $_REQUEST["holdlimit"];  // 持股上限
@$Sta_Test = $_REQUEST["sta_test"];    // 测试集开始时间
@$End_Test = $_REQUEST["end_test"];       // 测试集结束时间
@$DayBuy = $_REQUEST["one_buy"];       // 单日买入数
@$KeepHoldProfit = $_REQUEST["zhi_ying_rate"];       // 止盈收益率
@$HighestFall = $_REQUEST["max_huiluo"];       // 最大回落
@$StopLoseProfit = $_REQUEST["zhi_Sun"];       // 止损收益率
@$source = $_REQUEST["holdtime"];
@$compareWay = $_REQUEST["compareWay"];    // 指数

$train_save = array();
$test_save = array();
$train_star_all = array();
$train_end_all = array();
$test_star_all = array();
$test_end_all = array();

//利用 explode 函数分割字符串到数组
$holdtime = explode(',', $source);
$hold_time_array = array();
for ($index = 0; $index < count($holdtime); $index++) {
    array_push($hold_time_array, intval($holdtime[$index]));
}

/**
 * start back test 
 */
if ($source != null) {
    // get train time
    /**
     * process date
     * $Test_date = array();
     *for ($date_year = 1991; $date_year <= 2020; $date_year++) {
     *    for ($date_month = 1; $date_month <= 12; $date_month++) {
     *       array_push($Test_date, $date_year . '-' . $date_month . '-01');
     *   }
     *}
     * 
     * 
     * $save_Test_date=  json_encode($Test_date);
     * file_put_contents('Test_date.json', $save_Test_date);
     */

    $Test_date = file_get_contents('Test_date.json');
    $Test_date = json_decode($Test_date, true);
   
    // 360 mouth
    $train_time = 36;
    $test_time = 4;
    for ($i = 0; $i < count($Test_date) - $train_time - $test_time - 2; $i = $i + $test_time) {
        $Train_StartTime = $Test_date[$i];
        while (array_search($Train_StartTime, $TradeDate) == null) {
            $time = strtotime($Train_StartTime);
            $Train_StartTime = date("Y-m-d", strtotime("+1 day", $time));
        }
        $Train_EndTime = $Test_date[$i + $train_time];
        while (array_search($Train_EndTime, $TradeDate) == null) {
            $time = strtotime($Train_EndTime);
            $Train_EndTime = date("Y-m-d", strtotime("-1 day", $time));
        }
        // save time
        array_push($train_star_all, $Train_StartTime);
        array_push($train_end_all, $Train_EndTime);
    }
    // trian_time trade_time end 2020-09 so shoue be  -2

    for ($q = $train_time; $q < count($Test_date) - $test_time - 2; $q = $q + $test_time) {
        $Test_StartTime = $Test_date[$q];
        while (array_search($Test_StartTime, $TradeDate) == null) {
            $time = strtotime($Test_StartTime);
            $Test_StartTime = date("Y-m-d", strtotime("+1 day", $time));
        }
        // EndTime
        $Test_EndTime = $Test_date[$q + $test_time];
        while (array_search($Test_EndTime, $TradeDate) == null) {
            $time = strtotime($Test_EndTime);
            $Test_EndTime = date("Y-m-d", strtotime("-1 day", $time));
        }
        array_push($test_star_all, $Test_StartTime);
        array_push($test_end_all, $Test_EndTime);
    }
    // var_dump($train_star_all);
    // var_dump($train_end_all);
    // var_dump($test_star_all);
    // var_dump($test_end_all);
    var_dump(count($train_star_all));
    var_dump($test_star_all[64]); 
    // var_dump(count($train_star_all));  
    // 12 train_mouth :amount = 172
    // 24 train_mouth :amount = 166      from 134 to 163
    // 36 train_mouth :amount = 80
    //for ($m = 342; $m < count($train_star_all) -1; $m++) {    
    for ($m = 64; $m < 79; $m++) {
        //训练
        $best_para = Train_day(
            $train_star_all[$m],
            $train_end_all[$m],
            $hold_time_array,
            $HoldLimit,
            $DayBuy,
            $KeepHoldProfit,
            $HighestFall,
            $StopLoseProfit,
            $orderRule,
            null
        );
        if ($best_para != null) {
            $best_hold_day = $best_para["one"]['holdtime'];
            $AddBorder =  $best_para["two"];
            $stock_amount_left = $best_para["three"];
            array_push($train_save, $best_para["one"]);
            // 测试数据
            $res_para = Test_day(
                $test_star_all[$m],
                $test_end_all[$m],
                $best_hold_day,
                $HoldLimit,
                $DayBuy,
                $KeepHoldProfit,
                $HighestFall,
                $StopLoseProfit,
                $orderRule,
                $AddBorder,
                $stock_amount_left
            );
            array_push($test_save, $res_para);
        } else {
            $temp_train = array(
                "start_day" => $train_star_all[$m], "end_day" => $train_end_all[$m],
                "year_shouyi" => null, "ave_shouyi" => null, "max_shouyi" => null,
                "min_shouyi" => null, "trade_times" => null, "holdtime" => null,
                "real_shouyilv" => null, "max_huice" => null, "xiapu_rate" => null, "Mar_rate" => null
            );
            $temp_test =  array(
                "start_day" => $test_star_all[$m], "end_day" => $test_end_all[$m],
                "year_shouyi" => null, "ave_shouyi" => null, "max_shouyi" => null,
                "min_shouyi" => null, "trade_times" => null, "holdtime" => null,
                "real_shouyilv" => null, "max_huice" => null, "xiapu_rate" => null, "Mar_rate" => null
            );
            array_push($train_save, $temp_train);
            array_push($test_save, $temp_test);
        }
    }


    //var_dump($test_save);
    $test =  json_encode($test_save);
    file_put_contents('test.json', $test);
}



/**
 * 测试时间得到最优 持股周期 
 */
function Train_day($Sta_Test, $End_Test, $hold_time_array, $HoldLimit, $DayBuy, $KeepHoldProfit, $HighestFall, $StopLoseProfit, $orderRule, $AddBorder)
{
    global $AllarrayCalDay;
    global $train_fenxi;

    //var_dump($Sta_Test,$End_Test);
    $hold_time_count = count($hold_time_array); // 持股周期的循环内容
    for ($i = 0; $i < $hold_time_count; $i++) {
        $One_HoldLimit_Trade = oneActionMore(     // 每一种持股周期下的一次所有交易
            $Sta_Test,
            $End_Test,
            $hold_time_array[$i],
            $HoldLimit,
            $DayBuy,
            $KeepHoldProfit,
            $HighestFall,
            $StopLoseProfit,
            $orderRule,
            NULL  // 没有剩余持股量
        );

        // 计算指标  判空
        if ($One_HoldLimit_Trade != null) {
            //var_dump($One_HoldLimit_Trade);

            $calDay  = calculate_caption($One_HoldLimit_Trade, $HoldLimit, $Sta_Test, $End_Test, null);
            $calDay = $calDay["one"];
            foreach ($calDay as $key => $value) {
                $a = array((int)(strtotime($key) * 1000), $value);
                $b[] = $a;
            }
            $arrayCalDay = array("day:$hold_time_array[$i]" => $b);
            $b = (array)null;  // *清空数组
            array_push($AllarrayCalDay, $arrayCalDay);  // 保存到大数组

            $trade_analysis = calTarget($One_HoldLimit_Trade, $hold_time_array[$i], $HoldLimit, $Sta_Test, $End_Test, null);

            array_push($train_fenxi, $trade_analysis);   // 将所有的分析结果保存

        }
    }
    // 取得最好参数
    sort_array_of_array_desc($train_fenxi, "real_shouyilv");
    $best = array();
    @$best = $train_fenxi[0];
    $train_fenxi = (array)null;
    $best_hold_day = $best['holdtime'];
    if ($best != null) {
        // 获得最优参数下的 剩余股票
        $getFromOneAction = oneActionMore(     // 一种持股周期下的一次所有交易
            $Sta_Test,
            $End_Test,
            $best_hold_day,
            $HoldLimit,
            $DayBuy,
            $KeepHoldProfit,
            $HighestFall,
            $StopLoseProfit,
            $orderRule,
            NULL  // 没有剩余持股量
        );
        // 剩下的股票手数
        //var_dump($getFromOneAction);
        $stock_amount_left = calculate_caption($getFromOneAction, $HoldLimit, $Sta_Test, $End_Test, null)["two"];

        // 剩下的股票
        $left = (array)null;
        $left = leftMore($Sta_Test, $End_Test, $getFromOneAction);
        $res = array("one" => $best, "two" => $left, "three" => $stock_amount_left);
        return $res;
    } else {
        return null;
    }
}

/*
*  测试数据 & 股票的遗留处理
*/
function Test_day(
    $Sta_Test,
    $End_Test,
    $best_hold_day,
    $HoldLimit,
    $DayBuy,
    $KeepHoldProfit,
    $HighestFall,
    $StopLoseProfit,
    $orderRule,
    $AddBorder,
    $stock_amount_left
) {
    global $AllarrayCalDay;
    global $test_fenxi;
    $One_HoldLimit_Trade = oneActionMore(     // 每一种持股周期下的一次所有交易
        $Sta_Test,
        $End_Test,
        $best_hold_day,
        $HoldLimit,
        $DayBuy,
        $KeepHoldProfit,
        $HighestFall,
        $StopLoseProfit,
        $orderRule,
        $AddBorder  // 有剩余持股量
    );
    // var_dump($One_HoldLimit_Trade);
    // 计算指标  判空
    if ($One_HoldLimit_Trade != null) {
        // 传入股票
        $calDay  = calculate_caption($One_HoldLimit_Trade, $HoldLimit, $Sta_Test, $End_Test, $stock_amount_left);
        // 查看每日的市值 
        //var_dump($calDay);
        $calDay = $calDay["one"];
        foreach ($calDay as $key => $value) {
            $a = array((int)(strtotime($key) * 1000), $value);
            $b[] = $a;
        }

        $arrayCalDay = array("day:$best_hold_day" => $b);
        $b = (array)null;  // *清空数组
        array_push($AllarrayCalDay, $arrayCalDay);  // 保存到大数组
        $test_fenxi = calTarget($One_HoldLimit_Trade, $best_hold_day, $HoldLimit, $Sta_Test, $End_Test, $stock_amount_left);
        // var_dump($test_fenxi);
        //array_push($test_fenxi, $trade_analysis);   // 将所有的分析结果保存

        // 取得最好参数
        //sort_array_of_array_desc($test_fenxi, "real_shouyilv");

        return $test_fenxi;
    } else {
        return null;
    }
}
